
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.http

<Serializable()> Public Class Publisher
    Inherits MarshalByRefObject
    Private ServiceChannel As IChannel
    Private Reference As ObjRef
    Private ObjWellKnown As Publication
    ' Each publisher has a port that it registers a remoting server on.
    Public Port As Integer
    Public Host As String
    ' A publisher should have a list of all its publications so that it can
    ' add or remove publications as needed.
    Public Publications As New ArrayList

    Public Sub UnPublish()
        For Each p As Publication In Publications
            ' MsgBox(RemotingServices.GetObjectUri(p))
            'p = Nothing
            RemotingServices.Disconnect(p)
        Next

        'RemotingServices.Unmarshal(Reference)
        ChannelServices.UnregisterChannel(ServiceChannel)

        Reference = Nothing
        ServiceChannel = Nothing
    End Sub

    Public Sub New(ByVal Host As String, ByVal Port As Integer)
        Me.Host = Host
        Me.Port = Port

        Dim serverProv As BinaryServerFormatterSinkProvider = New BinaryServerFormatterSinkProvider
        Dim clientProv As BinaryClientFormatterSinkProvider = New BinaryClientFormatterSinkProvider
        Dim Props As IDictionary = New Hashtable
        'Dim IpInjProvider As New IpInjectorSinkProvider

        serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full
        Props("port") = Me.Port
        Props("name") = "DefaultShare"
        Try
            ServiceChannel = New HttpChannel(Props, clientProv, serverProv)
        Catch ex As Exception

        End Try


        ' We need to have channels ready in order to publish and subscribe
        ' to our own publications.  An exception is thrown when more than
        ' one server or client channel is registered.  Each local publisher
        ' or subscriber object needs its own channels, and we don't know if
        ' anyone has already asked for them.  We also can't assume that a
        ' channel will already be allocated, because a publisher can
        ' exist without a local subscriber.  So we need to encase these
        ' attempts inside of respective try catch blocks.
        Try
            ' We need to register a server channel to publish on.
            ChannelServices.RegisterChannel(ServiceChannel)
            'System.Runtime.Remoting.Services.TrackingServices.RegisterTrackingHandler(New MyTrackingHandler)
        Catch
            ' We don't care if the registration failed.  It probably means
            ' that the channel has already been asked for.
        End Try

        Try
            ' We need to register a client channel for ourselves so that we
            ' can subscribe to our own publications.
            ChannelServices.RegisterChannel(New HttpClientChannel)
        Catch
            ' We don't care if the registration failed.  It probably means
            ' that the channel has already been asked for.
        End Try
    End Sub

    ' When a new publication is needed by client code, it calls this
    ' function to set up the remoting side of the publication.
    Public Function NewPublication(ByVal URI As String) As Publication
        ' Give the remoting server a brand new publication.  We can't set
        ' any values on the publication until we acquire a managed copy.
        ObjWellKnown = New Publication
        ObjWellKnown.Name = URI
        Reference = RemotingServices.Marshal(ObjWellKnown, URI)

        ' Reference = RemotingServices.Connect(, URI)
        ' Use our client channel to request a copy of the publication.  For
        ' now, this assumes that we can refer to the machine as "localhost."
        Dim RemotePublication As Publication = RemotingServices.Connect(GetType(Publication), "http://" & Me.Host & ":" & Me.Port & "/" & URI)

        ' We had to wait to set any properties until we acquired the object
        ' managed by the remoting server.  Now we can set values.  For now,
        ' we are assuming that the default name of a publication will be its
        ' respective U.R.I. name.
        RemotePublication.Name = URI

        ' Make sure we add the remoting-managed publication to our list.
        Me.Publications.Add(ObjWellKnown)

        ' We need to return the remote publication to the client code so it
        ' can set any other options or variables needed.
        Return RemotePublication
    End Function

    ' When a new version of a publication needs to be issued, client code
    ' can call this function with the object to be included in the issue.
    Public Sub PublishIssue(ByRef Publication As Publication, ByVal Issue As Object)
        ' Raise an event in the remote publication that will apply to all
        ' current subscribers.
        Publication.PublishIssue(Issue)
    End Sub
End Class
